﻿// Decompiled with JetBrains decompiler
// Type: System.Web.Razor.Text.SourceLocationTracker
// Assembly: System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// MVID: 682513D6-F37E-48AC-9909-F3EE103CFF14
// Assembly location: D:\Project\Idea\无人机外网\uav\客户端工程\排查工具\bin\Release\System.Web.Razor.dll

using System.Web.Razor.Parser;

namespace System.Web.Razor.Text
{
  /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Provides a source location tracker.</summary>
  public class SourceLocationTracker
  {
    private int _absoluteIndex;
    private int _characterIndex;
    private int _lineIndex;
    private SourceLocation _currentLocation;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Initializes a new instance of the <see cref="T:System.Web.Razor.Text.SourceLocationTracker" /> class.</summary>
    public SourceLocationTracker()
      : this(SourceLocation.Zero)
    {
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Initializes a new instance of the <see cref="T:System.Web.Razor.Text.SourceLocationTracker" /> class.</summary>
    /// <param name="currentLocation">The current location of the source.</param>
    public SourceLocationTracker(SourceLocation currentLocation)
    {
      this.CurrentLocation = currentLocation;
      this.UpdateInternalState();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets or sets the current location of the source.</summary>
    /// <returns>The current location of the source.</returns>
    public SourceLocation CurrentLocation
    {
      get => this._currentLocation;
      set
      {
        if (!(this._currentLocation != value))
          return;
        this._currentLocation = value;
        this.UpdateInternalState();
      }
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Updates the source location.</summary>
    /// <param name="characterRead">The character to read.</param>
    /// <param name="nextCharacter">The character to update.</param>
    public void UpdateLocation(char characterRead, char nextCharacter)
    {
      this.UpdateCharacterCore(characterRead, nextCharacter);
      this.RecalculateSourceLocation();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Updates the location of the source.</summary>
    /// <returns>The <see cref="T:System.Web.Razor.Text.SourceLocationTracker" /> object.</returns>
    /// <param name="content">The content of the source.</param>
    public SourceLocationTracker UpdateLocation(string content)
    {
      for (int index = 0; index < content.Length; ++index)
      {
        char minValue = char.MinValue;
        if (index < content.Length - 1)
          minValue = content[index + 1];
        this.UpdateCharacterCore(content[index], minValue);
      }
      this.RecalculateSourceLocation();
      return this;
    }

    private void UpdateCharacterCore(char characterRead, char nextCharacter)
    {
      ++this._absoluteIndex;
      if (ParserHelpers.IsNewLine(characterRead) && (characterRead != '\r' || nextCharacter != '\n'))
      {
        ++this._lineIndex;
        this._characterIndex = 0;
      }
      else
        ++this._characterIndex;
    }

    private void UpdateInternalState()
    {
      this._absoluteIndex = this.CurrentLocation.AbsoluteIndex;
      this._characterIndex = this.CurrentLocation.CharacterIndex;
      this._lineIndex = this.CurrentLocation.LineIndex;
    }

    private void RecalculateSourceLocation() => this._currentLocation = new SourceLocation(this._absoluteIndex, this._lineIndex, this._characterIndex);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Calculates the new location of the source.</summary>
    /// <returns>The new source location.</returns>
    /// <param name="lastPosition">The last position.</param>
    /// <param name="newContent">The new content.</param>
    public static SourceLocation CalculateNewLocation(
      SourceLocation lastPosition,
      string newContent)
    {
      return new SourceLocationTracker(lastPosition).UpdateLocation(newContent).CurrentLocation;
    }
  }
}
